<?php
/**
 * 文件路径： \application\index\job\Hello.php
 * 这是一个消费者类，用于处理 helloJobQueue 队列中的任务
 */
namespace app\job;

use app\api\service\Order;
use think\Exception;
use think\queue\Job;

class PayNotify {

    /**
     * fire方法是消息队列默认调用的方法  支付状态回调
     * @param Job            $job      当前的任务对象
     * @param array|mixed    $data     发布任务时自定义的数据
     */
    public function fire(Job $job,$data)
    {
        // 检查当前订单是否存在或者是否已经支付
        $isPay = $this->checkOrderHasPay($data);
        if(!$isPay)
        {
            $job->delete();
            return;
        }

        //支付成功回调
        $isJobDone = $this->doPayJob($data);

        if ($isJobDone) {
            //如果任务执行成功， 记得删除任务
            log_info('支付回调任务执行成功!',json_encode($data));
            $job->delete();
        }else{
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                log_info('支付回调任务执行失败!',json_encode($data));
                $job->delete();
                // 也可以重新发布这个任务
                //print("<info>Hello Job will be availabe again after 2s."."</info>\n");
                //$job->release(2); //$delay为延迟时间，表示该任务延迟2秒后再执行
            }
        }
    }

    /**
     * 验证当前订单是否存在或已经支付成功
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function checkOrderHasPay($data)
    {
        try{
            $order_sn = $data['out_trade_no'];
            $order = db('order')->where('order_sn',$order_sn)->find();
            if(!$order) return false;
            if($order['pay_status'] == 1) return false;
            return true;
        }catch (Exception $exception){
            log_error('支付回调验证是否需要执行',$exception->getMessage());
            return false;
        }

    }

    /**
     * 根据消息中的数据进行实际的业务处理
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function doPayJob($data)
    {
        // 根据消息中的数据进行实际的业务处理...
        $OrderService = new Order();
        $res = $OrderService->payNotifyOrder($data['out_trade_no'],$data['transaction_id']);
        if(!$res['code'])
        {
            log_error('支付回调执行结果',$res['msg']);
            return false;
        }
        return true;
    }


    /**
     * 该方法用于接收任务执行失败的通知，你可以发送邮件给相应的负责人员
     * @param $jobData  string|array|...      //发布任务时传递的 jobData 数据
     */
    public function failed($jobData)
    {
        log_error('支付回调任务重复执行失败',json_encode($jobData));
    }

}